<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      console.log("" + 1 + 0); // "10"， 字符串连接
      console.log("" - 1 + 0); // -1，进行算术运算，""转换为0，
      console.log(true + false); // 1，进行算术运算，true转换为1，false转换为0
      console.log(6 / "3"); // 2，"3"被隐式转换为数字3，然后进行除法运算 6 / 3 = 2  
      console.log("2" * "3"); // 6，"2"和"3"都被隐式转换为数字2和3，然后进行乘法运算 2 * 3 = 6  
      console.log(4 + 5 + "px"); // "9px"，先计算4 + 5 = 9，然后将9与"px"连接成字符串"9px"  
      console.log("$" + 4 + 5); // "$45"，"$"与4连接成"$4"，然后与5连接成"$45"  
      console.log("4" - 2); // 2，"4"被隐式转换为数字4，然后进行减法运算 4 - 2 = 2  
      console.log("4px" - 2); // NaN，"4px"无法被转换为有效的数字，因此结果为NaN  
      console.log("  -9  " + 5); // "  -9  5"，字符串与数字相加时，数字转为字符串后连接  
      console.log("  -9  " - 5); // -14，"  -9  "被转换为-9（前导空格被忽略），然后进行减法运算 -9 - 5 = -14  
      console.log(null + 1); // "1"，null转换为字符串"null"后与1相加，但"null"被忽略，结果为"1"（这里解释有误，应为"null"与1连接成"null1"）  
      // 更准确的解释：console.log(null + 1); // "null1"，null被转换为字符串"null"，然后与数字1连接  
      console.log(undefined + 1); // "undefined1"，undefined转换为字符串"undefined"后与1相加，但"undefined"被转换为字符串后与1连接  
      // 更准确的解释：console.log(undefined + 1); // "undefined1"，undefined被转换为字符串"undefined"，然后与数字1连接  
      console.log(" \t \n" - 2); // NaN，"\t \n"（制表符和换行符）无法被转换为有效的数字，因此结果为NaN  
      console.log(0 == true); // true，0与true在比较时都被转换为数字，0 == 1（true转换为1）为false，但==会进行类型转换，所以这里比较的是0与转换为数字后的true（即1）是否相等（这里解释有误，应为0在==比较时会被视为false，而true在==比较时会被视为1的非零值，但在JavaScript中，任何非零值在==比较时都被视为true，而0被视为false，因此这里的结果是true，尽管这个逻辑有些绕，但关键是理解==会进行类型转换）  
      // 更简洁的解释：console.log(0 == true); // true，因为==会进行类型转换，将0视为false，将true视为true（在比较上下文中），而false与true在宽松比较下不相等，但这里的特殊之处在于0（视为false）与true（非零值，视为true）在==下会被视为不相等之外的“特殊情况”，即JavaScript中0与任何非零值在==下都不会相等，但这里的比较实际上是看0（宽松比较下视为false）是否能与true（宽松比较下视为非零/true）“等价”，由于JavaScript的==有将false与0视为等价的“特性”，所以这里的结果是true（这个解释有些绕，但关键是理解==的宽松比较和JavaScript的类型转换规则）  
      // 然而，更准确的解释应该是：在==比较中，0会被转换为false，而true保持为true（或更准确地说，是被视为1的非零值），但==比较会尝试将两边转换为相同的类型进行比较。在这里，由于0被视为false（在布尔上下文中），而true在布尔上下文中就是true，它们本不应该相等。但是，JavaScript的==有一个“特性”，即当一边是数字0或NaN，另一边是布尔值时，它会将布尔值转换为数字（true为1，false为0）进行比较。因此，0（作为数字）与true（在==比较中被视为1）本不相等，但由于这个特殊的转换规则，0（宽松比较下与false等价）在这里被视为与true（宽松比较下与非零/true等价，但在具体比较时被视为1）有某种“等价性”，导致结果为true。然而，这个解释仍然有些复杂，更简单的理解是：在JavaScript中，0 == true的结果是true，这是==比较的一个已知“陷阱”，应该避免使用==进行比较，而是使用===进行严格比较。  
      // 为了避免混淆，建议使用严格相等运算符===进行比较，它不会进行类型转换。  
      console.log(1 == true); // true，同上解释，但这次是1与true比较，1在==比较中被视为true（非零值），因此结果为true（但同样建议使用===进行比较）  
      console.log(1 === true); // false，===进行严格比较，不会进行类型转换，1（数字）与true（布尔值）不相等  
      console.log("a" == false); // false，"a"（非空字符串）在==比较中不会被转换为0或false，因此与false不相等  
      console.log("" == false); // true，空字符串""在==比较中被视为0（或false），因此与false相等（但这里同样建议使用===进行比较，以避免潜在的混淆）  
      console.log("" === false); // false，===进行严格比较，不会进行类型转换，空字符串（字符串类型）与false（布尔类型）不相等  
      console.log(undefined == null); // true，undefined和null在==比较中被视为相等（但同样建议使用===进行比较，以避免潜在的混淆）  
      console.log(undefined === null); // false，===进行严格比较，undefined（undefined类型）与null（null类型）不相等  
      console.log(!3); // false，!是逻辑非运算符，3是非零值，因此为true，再取反得到false  
      console.log(!!3); // true，!!是两次逻辑非运算，相当于将3转换为布尔值后再取反再取反，结果为true  
      console.log(123 || null || "abc"); // 123，||是逻辑或运算符，返回第一个真值（truthy value），123是真值，因此返回123  
      console.log(0 || null || "abc"); // "abc"，0是假值（falsy value），null也是假值，因此返回第三个参数"abc"  
      console.log(0 || null || undefined); // undefined，0、null和undefined都是假值，但||运算符会返回最后一个假值（在这个例子中是undefined），因为没有任何真值来中断这个链  
      console.log(123 && null && "abc"); // null，&&是逻辑与运算符，返回第一个假值或最后一个真值，这里123是真值，但null是假值，因此返回null  
      console.log(0 && null && "abc"); // 0，0是假值，因此&&运算符不会继续评估后面的表达式，直接返回0  
      console.log(123 && [] && "abc"); // "abc"，123和空数组[]都是真值（因为空数组在JavaScript中被视为真值），因此返回最后一个真值或假值之后的值，即"abc"  
      console.log(123 ?? "abc"); // 123，??是逻辑空值合并运算符，返回其左侧的第一个非空值（non-nullish value），123不是null或undefined，因此返回123  
      console.log(null ?? "abc"); // "abc"，null是空值（nullish value），因此??运算符返回其右侧的"abc"  
    </script>  
  </body>  
</html>
